<?php

/**
 * hotel.php
 *
 * Author: netman
 * DateTime:  2023/9/11 16:37
 */
class Service_Api_Hotel extends Contract_Api_Product
{
    use Trait_Api_Hotel;
    use Trait_Api_Common;

    /**
     * @var Service_Api_Fenxiao
     */
    private $fenxiao_service = null;
    /**
     * 类型ID
     */
    const TYPE_ID = 2;

    public function __construct()
    {
        $this->fenxiao_service = new Service_Api_Fenxiao();
    }

    /**
     * 产品搜索
     * @param array $params
     * @return array
     * User: netman
     * Date: 2023/9/11 17:47
     */
    function search(array $params = array()): array
    {
        $status   = true;
        $mid      = $params['member_id'] ?? '';
        $destPy   = $params['destpy'];
        $rankId   = (int)$params['rankid'];
        $priceId  = (int)$params['priceid'];
        $sortType = (int)$params['sorttype'];
        $attrId   = $params['attrid'];
        $page     = $params['page'];
        $keyword  = $params['keyword'];
        $page     = $page ? $page : 1;
        $pagesize = $params['pagesize'];
        $platform_no = $params['platform_no'];
        $pagesize = $pagesize ? $pagesize : 12;

        //经度,纬度附近酒店

        if ($params['lat'] && $params['lng']) {
            $lat       = round($params['lat'], 3);
            $lng       = round($params['lng'], 3);
            $distance  = $params['distance'];
            $add_field = "  ROUND(6378.138*2*ASIN(SQRT(POW(SIN((" . $lat . "*PI()/180-FORMAT(sline_hotel.lat,3)*PI()/180)/2),2)+COS(" . $lat . "*PI()/180)*COS(FORMAT(sline_hotel.lat,3)*PI()/180)*POW(SIN((" . $lng . "*PI()/180-FORMAT(sline_hotel.lng,3)*PI()/180)/2),2)))*1000) AS distance";
            $where     = " sline_hrp.supplier_channel_id=1 and sline_hotel.lat>0 and sline_hotel.lng>0 and ROUND(6378.138*2*ASIN(SQRT(POW(SIN((" . $lat . "*PI()/180-FORMAT(sline_hotel.lat,3)*PI()/180)/2),2)+COS(" . $lat . "*PI()/180)*COS(FORMAT(sline_hotel.lat,3)*PI()/180)*POW(SIN((" . $lng . "*PI()/180-FORMAT(sline_hotel.lng,3)*PI()/180)/2),2)))*1000)<$distance ";
            $builder   = DB::select(DB::expr('`sline_hotel`.*,(IFNULL(`sline_hotel`.bookcount,0)+IFNULL(d.sell,0)) AS sellnum'), DB::expr($add_field))
                ->from('hotel')
                ->distinct(true)
                ->join(array('hotel_room_price', 'hrp'), 'left')
                ->on("hrp.hotelid", '=', 'hotel.id')
                ->join(DB::expr("(SELECT sum(dingnum) as sell,`sline_member_order`.productautoid FROM `sline_member_order` WHERE `sline_member_order`.typeid=2 GROUP BY `sline_member_order`.productautoid) AS d"), 'left')
                ->on(DB::expr('d.productautoid'), '=', 'hotel.id')
                ->join(array('allorderlist', 'b'), 'left')
                ->on("hotel.id", '=', 'b.aid')
                ->on('b.typeid', '=', self::TYPE_ID)
                ->on('hotel.webid', '=', 'b.webid')
                ->where(DB::expr($where));


        } //如果选择了目的地
        else if ($destPy && $destPy != 'all' && $destPy != 'undefined') {
            $dest_id  = DB::select('id')->from('destinations')->where('pinyin', '=', $destPy)->execute()->get('id');
            $builder = DB::select(DB::expr('`sline_hotel`.*,(IFNULL(`sline_hotel`.bookcount,0)+IFNULL(d.sell,0)) AS sellnum'))
                ->from('hotel')
                ->distinct(true)
                ->join(array('kindorderlist', 'b'), 'left')
                ->on("hotel.id", '=', 'b.aid')
                ->on('b.typeid', '=', self::TYPE_ID)
                ->on('hotel.webid', '=', 'b.webid')
                ->on('b.classid', '=', (int)$dest_id);
            $builder->join(DB::expr("(SELECT sum(dingnum) as sell,`sline_member_order`.productautoid FROM `sline_member_order` WHERE `sline_member_order`.typeid=2 GROUP BY `sline_member_order`.productautoid) AS d"), 'left')
                ->on(DB::expr('d.productautoid'), '=', 'hotel.id');
            $builder->join(array('hotel_room_price', 'hrp'), 'left')
                ->on("hrp.hotelid", '=', 'hotel.id');

        } else {

            $builder = DB::select(DB::expr('`sline_hotel`.*,(IFNULL(`sline_hotel`.bookcount,0)+IFNULL(d.sell,0)) AS sellnum'))
                ->from('hotel')
                ->distinct(true)
                ->join(array('allorderlist', 'b'), 'left')
                ->on("hotel.id", '=', 'b.aid')
                ->on('b.typeid', '=', self::TYPE_ID)
                ->on('hotel.webid', '=', 'b.webid');

            $builder->join(DB::expr("(SELECT sum(dingnum) as sell,`sline_member_order`.productautoid FROM `sline_member_order` WHERE `sline_member_order`.typeid=2 GROUP BY `sline_member_order`.productautoid) AS d"), 'left')
                ->on(DB::expr('d.productautoid'), '=', 'hotel.id');
            $builder->join(array('hotel_room_price', 'hrp'), 'left')
                ->on("hrp.hotelid", '=', 'hotel.id');
        }
        $builder->where('hotel.status', '=', 3)
            ->and_where(DB::expr(" and FIND_IN_SET({$platform_no},sline_hotel.platform)"));

        //入住时间
        if (!empty($params['starttime']) && !empty($params['endtime']) && $params['starttime'] != $params['endtime']) {
            $builder->and_where('hrp.day', '>=', $params['starttime'])->and_where('hrp.day', '<', $params['endtime']);
        } elseif (!empty($params['starttime']) || !empty($params['endtime'])) {
            //只有入住日期或离开日期
            $time = empty($params['starttime']) ? $params['endtime'] : $params['starttime'];
            $builder->and_where('hrp.day', '>=', $time);
        }
        //按目的地搜索
        if (!empty($dest_id)) {
            $builder->and_where(DB::expr(" and FIND_IN_SET('$dest_id',sline_hotel.kindlist)"));
        }

        //星级
        if ($rankId) {
            $builder->and_where(DB::expr(" and sline_hotel.hotelrankid='$rankId'"));
        }
        //价格区间
        if ($priceId) {
            $priceArr = DB::select()->from('hotel_pricelist')->where('id', '=', $priceId)->execute()->current();
            $builder->and_where(DB::expr(" and sline_hotel.price BETWEEN {$priceArr['min']} AND {$priceArr['max']}"));
        }
        //关键词
        if (!empty($keyword)) {
            $builder->and_where(DB::expr(' and sline_hotel.title like ' . '"%' . $keyword . '%"'));
        }
        //按属性
        if (!empty($attrId)) {
            $where = $this->get_attr_where($attrId);
            $builder->and_where(DB::expr($where));
        }
        //排序
        if (!empty($sortType)) {
            if ($sortType == 1)//价格升序
            {
                $builder->order_by('hotel.price', 'asc');
            } else if ($sortType == 2) //价格降序
            {
                $builder->order_by('hotel.price', 'desc');

            } else if ($sortType == 3) //销量降序
            {
                $builder->order_by('sellnum', 'desc');

            } else if ($sortType == 4)//推荐
            {
                $builder->order_by('hotel.recommendnum', 'desc');
            }
        }
        $builder->order_by(DB::expr("IFNULL(sline_b.displayorder,9999)"), 'asc');
        $builder->order_by('hotel.modtime', 'desc');
        $builder->order_by('hotel.addtime', 'desc');

        $total = $builder->execute()->count();
        //检测页面数量是否超限
        $status     = true;
        $total_page = (int)ceil($total / $pagesize);
        if (($total_page > 0 and (int)$page > $total_page) or ($total_page == 0 and $page > 1)) {
            $status = false;
        }

        if ($page && $pagesize) {
            $offset = St_Page::offset($page, $pagesize);
            $builder->offset($offset)->limit($pagesize);
        }
        $arr    = $builder->execute()->as_array();
        $hotels = [];
        if(!empty($arr)){
            // 获取营销策略
            $marketing_strategy = Model_Api_V2_Marketing_Strategy::get_instance(self::TYPE_ID, array('mid'=> $mid));
            $uni_img = Model_Uniapp_Images::get_img_list(self::TYPE_ID);
            foreach ($arr as $v) {
                if(isset($uni_img[$v['id']])){
                    $v['litpic'] = $uni_img[$v['id']];
                }
                $hotels[] = [
                    'id'                 => $v['id'],
                    'litpic'             => $this->img_url($v['litpic'], 750, 750),
                    'title'              => $v['title'],
                    'satisfyscore'       => St_Functions::get_satisfy(self::TYPE_ID, $v['id'], $v['satisfyscore']),
                    'commentnum'         => Model_Comment::get_comment_num($v['id'], self::TYPE_ID), //评论次数
                    'sellpoint'          => $v['sellpoint'],
                    'lat'                => $v['lat'],
                    'lng'                => $v['lng'],
                    'attrlist'           => Model_Hotel_Attr::get_attr_list($v['attrid']),
                    'price'              => Model_Hotel::get_minprice($v['id'], $v),
                    'sellprice'          => Model_Hotel::get_sellprice($v['id']),
                    'discount_min_price' => $mid ? Model_Api_V2_Discount::get_discount($mid, 2, $v['id'], $v['price']) : 0,
                    'distance'           => $v['distance'] ?? 0,
                    'marketing_strategy' => $marketing_strategy->get_support_application($v['id']),
                    'icon_list'          => Product::get_ico_list($v['iconlist']),
                    'star_rating'        => $v['hotelrankid'] ? ORM::factory('hotel_rank', $v['hotelrankid'])->get('hotelrank') : 0
                ];
            }
        }
        return array(
            'total' => $total,
            'list' => $hotels,
            'status' => $status,
            'offset' => $offset,
            'pagesize' => $pagesize
        );
    }

    /**
     * 产品详情
     * @param array $params
     * @return array
     * @throws Kohana_Exception
     * User: netman
     * Date: 2023/9/11 16:39
     */
    function info(array $params = array()): array
    {
        if ($params['id']) {
            $id     = $params['id'];
            $mid    = $params['mid'];
            $fields = ['id', 'title', 'seotitle', 'keyword', 'description', 'sellpoint', 'hotelrankid', 'telephone', 'postcode'
                , 'content', 'address', 'price', 'price_date', 'shownum', 'addtime', 'litpic', 'kindlist', 'attrid', 'traffic',
                'aroundspots', 'notice', 'equipment', 'piclist', 'opentime', 'decoratetime', 'satisfyscore', 'supplierlist',
                'recommendnum', 'lng', 'lat', 'fuwu', 'jifenbook_id', 'jifentprice_id', 'servicelist', 'product_video', 'bookcount', 'status','platform'
            ];
            $platform_no = $params['platform_no'] ;
            $info   = DB::select_array($fields)
                ->from('hotel')
                ->where('id', '=', $id)
                ->and_where('status', '=', 3)
                ->and_where(DB::expr(" and FIND_IN_SET({$platform_no},platform)"))
                ->execute()
                ->current();
            if (!$info) {
                return array();
            }

            //产品图片jifenbook_info
            $uni_img = Model_Uniapp_Images::get_img_list(self::TYPE_ID,2);
            if(isset($uni_img['piclist'][$info['id']])){
                $info['piclist'] = $uni_img['piclist'][$info['id']];
                $info['litpic']  = $uni_img['litpic'][$info['id']];
            }
            $piclist = Product::pic_list($info['piclist']);
            $p       = array();
            foreach ($piclist as &$pic) {
                $pi = $this->img_url($pic[0], 750, 750);
                array_push($p, $pi);
            }
            unset($info['piclist']);
            if (empty($p)) {
                $p[0] = $this->img_url('');
            }
            $info['pic_list'] = $p;
            //属性列表
            $info['attr_list'] = Model_Hotel::hotel_attr($info['attrid']);
            $info['price']     = Model_Hotel::get_minprice($info['id'], array('info' => $info));
            // 销售状态 0电询 1可订 2售罄
            $info['sell_out']  = St_Functions::is_sell_out(2,$info['id'],'',$params);
            $info['sellprice'] = Model_Hotel::get_sellprice($info['id']);
            $info['rank_name'] = Model_Member::member_rank($mid, array('return' => 'current'));
            unset($info['price_date']);
            //点评数
            $info['commentnum'] = Model_Comment::get_comment_num($info['id'], self::TYPE_ID);
            //销售数量
            $info['sellnum'] = Model_Member_Order::get_sell_num($info['id'], self::TYPE_ID) + (int)($info['bookcount']);
            //产品编号
            $info['series'] = St_Product::product_series($info['id'], self::TYPE_ID);
            //产品图标
            $info['icon_list'] = Product::get_ico_list($info['iconlist']);
            unset($info['iconlist']);
            //满意度
            $info['score']    = St_Functions::get_satisfy(self::TYPE_ID, $info['id'], $info['satisfyscore']);
            $info['satisfy']    = str_replace('%','',$info['score']);
            $info['litpic']   = $this->img_url($info['litpic']);
            $info['basehost'] = $GLOBALS['cfg_basehost'];
            $info['lat']      = (float)$info['lat'];
            $info['lng']      = (float)$info['lng'];
            //扩展字段信息
            $extend_info         = ORM::factory('hotel_extend_field')
                ->where("productid=" . $info['id'])
                ->find()
                ->as_array();
            $info['extend_info'] = $extend_info;
            $info['content']     = Model_Api_V2_Xcx::filter_content($info['content']);
            //详情内容
            $params                 = array(
                'typeid' => self::TYPE_ID,
                'productinfo' => $info,
                'onlyrealfield' => 1,
                'pc' => 0
            );
            $info['introduce_list'] = $this->get_detail_content($params);
            // 更加ID查询可用的优惠券
            if (St_Functions::is_normal_app_install('coupon')) {
                $coupon_list = Model_Coupon::xcx_get_product_coupon_list($info['id'], self::TYPE_ID, $mid);
                $coupons     = [];
                foreach ($coupon_list as $coupon) {
                    $coupons[] = $this->filter_data(array('id', 'name'), $coupon);
                }
                $info['coupon_list'] = $coupons;
            }
            //会员折扣
            $info['discount_min_price'] = Model_Api_V2_Discount::get_discount($mid, self::TYPE_ID, $id, $info['price']);
            //分销赚取的金额
            if (St_Functions::is_normal_app_install('mobiledistribution')) {
                $info['profit'] = $this->fenxiao_service->get_estimate_profit(self::TYPE_ID, $mid, $info['id'], $info['price']);
            }
            //格式化数据
            $info = $this->format_detail($info);
            return $info;
        } else {
            return array();
        }
    }

    /**
     * 产品查询条件
     * @return array
     * User: netman
     * Date: 2023/9/11 17:48
     */
    function query_condition(): array
    {
        $data = array(
            'sort' => array(
                array('id' => 0, 'name' => '综合排序'),
                array('id' => 1, 'name' => '价格从低到高'),
                array('id' => 2, 'name' => '价格从高到低'),
                array('id' => 3, 'name' => '销量优先'),
                array('id' => 4, 'name' => '人气推荐')
            ),
            'star' => array('name' => '星级', 'child' => array()),
            'price' => array('name' => '价格', 'child' => array())
        );

        //星级
        $data['star']['child'] = $this->get_ranks();

        //价格
        $data['price']['child'] = $this->get_prices();

        // 属性
        $data['attribute'] = $this->get_attributes();

        return $data;
    }

    /**
     * 创建订单
     * @param array $params
     * @return array
     * @throws Exception
     * User: netman
     * Date: 2023/9/13 16:24
     */
    function create_order(array $params = array()): array
    {
        // 检查用户
        $member_id = $params['mid'];
        $member_info = $params['member_info'];

        // 检查提交的订单信息
        list($hotel, $hotel_room, $price, $extend_data) = $this->check_order_params($params, $member_id);

        // 创建订单基础数据
        $order = $this->make_order_data($params, $hotel, $hotel_room, $price, $extend_data);

        // 处理额外数据
        $order['memberid'] = $member_id;
        //积分抵现
        $jifen_info            = $this->make_jifen_info($params['needjifen'], $hotel, $member_info);
        $order['needjifen']    = $jifen_info['need_jifen'];
        $order['usejifen']     = $jifen_info['use_jifen'];
        $order['jifentprice']  = $jifen_info['jifen_price'];
        $order['jifencomment'] = $jifen_info['jifen_comment'];

        // 计算价格相关信息
        $seckill_id = (int)$params['seckill_id'];
        if ($seckill_id > 0) {
            $seckill = DB::select()
                ->from('seckill')
                ->where('id', '=', $seckill_id)
                ->execute()
                ->current();
            if (!$seckill) {
                throw new Exception('秒杀活动不存在');
            }

            $seckill['suit_original_adult_price'] = $price;
            $order['dingjin']                     = 0;
        }

        $order['price'] = $price;

        // 处理优惠券
        $coupon_id = Arr::get($params, 'couponid', 0);
        if ($coupon_id) {
            $coupon_check = Model_Api_V2_Coupon::order_use_coupon_check($coupon_id, $member_id, $order);
        }

        /*附加信息*/
        $order_params = array(
            'member_card_id' => $params['member_card_id'],
            'card_tourist_id' => $params['card_tourist_id'],
        );

        // 判断拼团是否允许使用会员折扣
        if (isset($extend_data['together_info']['discount_limit'])) {
            if (!in_array(Model_Together::ALLOW_DISCOUNT_TYPE_MEMBER_DISCOUNT, $extend_data['together_info']['discount_limit'])) {
                $order_params['use_member_discount'] = false;
            }
        }

        // 秒杀不使用会员折扣
        $seckill_id = Arr::get($params, 'seckill_id', '');
        if($seckill_id) {
            $order_params['use_member_discount'] = false;
        }

        // 添加订单
        $out = Model_Api_V2_Order::add_order($order, 'Model_Hotel', $order_params);

        if ($out && is_array($out) && $out['status'] == 1) {

            $order_info            = Model_Member_Order::order_info($order['ordersn']);
            $order_id              = $order_info['id'];
            $order_info['orderid'] = $order_id;

            // 添加优惠券使用
            if(!empty($coupon_check)){
                Model_Coupon::add_coupon_order($coupon_check['cid'], $order['ordersn'], $coupon_check['order_total_price'], $coupon_check, $coupon_id);
            }

            //秒杀过来的就添加关联订单
            if (isset($seckill) && $seckill) {
                Model_Seckill::add_seckill_order($order_info, $seckill);
            }

            // 添加拼团订单
            if (isset($extend_data['together_info'])) {
                Model_Api_V2_Together::add_order($extend_data['together_info'], $order_info);
            }

            //添加红包抵扣
            $envelope_member_id = (int)$params['envelope_member_id'];
            if ($envelope_member_id) {
                if (St_Functions::is_normal_app_install('red_envelope')) {
                    Model_Order_Envelope::order_use_envelope($envelope_member_id, $order['ordersn'], Model_Api_V2_Hotel::TYPE_ID, $member_id);
                }
            }
            // 添加游客信息
            $this->add_order_tourer( $order_id,json_decode($params['tourist'],true));

            //订单结算信息表数据更新
            Model_Member_Order_Compute::update($order['ordersn']);

            // 订单创建完成事件
            Hook::trigger('order_created', $order_info);

            // 返回订单信息
            $filter_keys = array('id', 'orderid', 'ordersn', 'pageType', 'typeid', 'status');
            return $this->filter_data($filter_keys, $order_info);

        } else {
            throw new Exception((isset($out['msg'])) ? $out['msg'] : '酒店下单失败');
        }

    }


}